#pragma once

#include "xyu.h"
#include "Task.h"
#include "Result.h"
#include "Semaphore.h"
#include "Thread.h"

namespace util
{
	class ThreadPool
	{
        // cfg
		Config cfg_;

		// thread
		std::unordered_map<int, std::unique_ptr<Thread>> threadQue_;

        // Task
        std::deque<std::shared_ptr<Task>> taskQue_;

        // sync
        std::mutex taskMtx_;
        std::condition_variable notEmptyCond_;
        std::condition_variable notFullCond_;

	public:/* interface methods */
		ThreadPool(int taskMax = 1024, int threadMin = 1, int threadMax = std::thread::hardware_concurrency());
		~ThreadPool();

        // interface
        Result submit(std::shared_ptr<Task> task);

		// nocopyable
		ThreadPool(const ThreadPool&) = delete;
		ThreadPool& operator=(const ThreadPool&) = delete;

        void start();

    private:    /* Internal methods */
        void consumerFunc(int);
	};

}	/* namespace util */

